package org.ruoyi.common.dhuman.backup;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 视频叠加处理器
 * 使用FFmpeg将两个视频进行叠加处理，将result.mp4叠加到bg.mp4的右下角
 */
public class VideoOverlayProcessor {
    
    private String ffmpegPath;

    /**
     * 构造函数
     *
     * @param ffmpegPath FFmpeg可执行文件路径，如果为null则使用系统PATH中的ffmpeg
     */
    public VideoOverlayProcessor(String ffmpegPath) {
        this.ffmpegPath = ffmpegPath != null ? ffmpegPath : "ffmpeg";
    }

    /**
     * 将resultVideo叠加到bgVideo的右下角
     * resultVideo约占屏幕六分之一大小
     *
     * @param bgVideoPath 背景视频路径 (bg.mp4)
     * @param resultVideoPath     前景视频路径 (result.mp4)
     * @param outputPath          输出视频路径
     * @throws IOException          IO异常
     * @throws InterruptedException 中断异常
     */
    public void overlayVideos(String bgVideoPath, String resultVideoPath, String outputPath)
            throws IOException, InterruptedException {
        
        // 检查输入文件是否存在
        if (!new File(bgVideoPath).exists()) {
            throw new IOException("背景视频文件不存在: " + bgVideoPath);
        }

        if (!new File(resultVideoPath).exists()) {
            throw new IOException("前景视频文件不存在: " + resultVideoPath);
        }

        // 构建FFmpeg命令
        List<String> command = buildFFmpegCommand(bgVideoPath, resultVideoPath, outputPath);

        // 执行FFmpeg命令
        executeCommand(command);
    }

    /**
     * 构建FFmpeg命令
     *
     * @param bgVideoPath 背景视频路径
     * @param resultVideoPath     前景视频路径
     * @param outputPath          输出视频路径
     * @return FFmpeg命令列表
     */
    private List<String> buildFFmpegCommand(String bgVideoPath, String resultVideoPath, String outputPath) {
        List<String> command = new ArrayList<>();
        command.add(ffmpegPath);
        
        // 输入文件
        command.add("-i");
		// 背景视频作为第一输入
        command.add(bgVideoPath);
        command.add("-i");
		// 前景视频作为第二输入
        command.add(resultVideoPath);

        // 使用滤镜处理视频叠加
        command.add("-filter_complex");
        // 将前景视频缩小到原始大小的1/6左右，并放置在背景视频的右下角
        command.add("[1:v]scale=iw/6:ih/6[fg];[0:v][fg]overlay=main_w-overlay_w-10:main_h-overlay_h-10");

        // 设置输出格式和编码参数
        command.add("-c:v");
		// 使用H.264编码
        command.add("libx264");
        command.add("-crf");
		// 视频质量控制
        command.add("23");
        command.add("-preset");
		// 编码速度和压缩率的平衡
        command.add("medium");
        command.add("-pix_fmt");
		// 像素格式（兼容性好）
        command.add("yuv420p");
        command.add("-c:a");
		// 音频流重新编码以兼容输出格式
        command.add("aac");
        command.add("-b:a");
		// 音频比特率
        command.add("128k");
		// 输出文件
        command.add(outputPath);

        return command;
    }

    /**
     * 执行命令
     *
     * @param command 命令列表
     * @throws IOException          IO异常
     * @throws InterruptedException 中断异常
     */
    private void executeCommand(List<String> command) throws IOException, InterruptedException {
        System.out.println("执行命令: " + String.join(" ", command));

        ProcessBuilder processBuilder = new ProcessBuilder(command);
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();

        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }

        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("FFmpeg处理失败，退出码: " + exitCode);
        }
    }

    /**
     * 主方法 - 执行视频叠加处理
     */
    public static void main(String[] args) {
        // 指定视频文件路径
        String bgVideoPath = "C:\\Users\\Admin\\Videos\\bg.mp4";
        String resultVideoPath = "C:\\Users\\Admin\\Videos\\result.mp4";
        String outputPath = "C:\\Users\\Admin\\Videos\\output_overlay.mp4";

        // 创建处理器实例
        VideoOverlayProcessor processor = new VideoOverlayProcessor(null);

        File bgVideoFile = new File(bgVideoPath);
        File resultVideoFile = new File(resultVideoPath);

        // 检查输入文件是否存在
        if (!bgVideoFile.exists()) {
            System.err.println("错误: 背景视频文件不存在 - " + bgVideoPath);
            return;
        }

        if (!resultVideoFile.exists()) {
            System.err.println("错误: 前景视频文件不存在 - " + resultVideoPath);
            return;
        }

        try {
            System.out.println("开始视频叠加处理...");
            System.out.println("背景视频: " + bgVideoPath);
            System.out.println("前景视频: " + resultVideoPath);
            System.out.println("输出文件: " + outputPath);

            processor.overlayVideos(bgVideoPath, resultVideoPath, outputPath);

            System.out.println("视频叠加处理完成!");
            System.out.println("输出文件位置: " + outputPath);

        } catch (Exception e) {
            System.err.println("视频处理失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}